"""
    Name: neural_networks.py
    Purpose: Create a neural network specifically designed to 
	     play the Finito game
    Author: Erin
"""
import sorto_game as sorto
import numpy

# Week 1:
# Wrote Skeleton

# Week 2:
# Started code, including
# initializing weights and
# integration with the Sorto machine
# Notes below

# Week 3:


### Notes:

# Input will be dice roll, tiles, and board
# Output will be the spot on the board where
# the neural net decides to place the tile

# I'm a little bit lost on how to evaluate and
# update weights. Right now I've been thinking
# one weight per input (eg per counter, per board spot,
# and per dice roll) but I'm not sure how helpful
# that will be.

# What I really need is a method of adapting choices
# so that, in a certain board/counter/roll situation,
# the best choice is made, and as-is the inputs and
# 'neurons' aren't really talking to each other
# They should probably be more dependant
# I'm not sure how to do that
 
class NeuralNetwork(object):

    def __init__(self):
        self.counter_weights = []
        self.board_weights = []
        self.dice_weight = []
        self.game_history = [] # number moves till win
        pass


    def initialize_weights(self, counters, board):
        """ Return initialized weights """
        for x in len(counters):
            self.counter_weights.append(random(0,1))
        for x in len(board.places): # does not exist
            self.board_weights.append(random(0,1))
        dice_weight.append(random(0,1))
        pass


    def print_current_weights(self):
        """ Print current weights """
        print "Counter weights: ", self.counter_weights
        print "Board weights: ", self.board_weights
        print "Dice weight: ", self.dice_weight

   
    def evaluate_output(self, pattern):
        """ Evaluate weights based on pattern """
        # Something here needs to decide if plays were
        # 'good' or 'bad
        # if 'good', increase weight
        # if 'bad', decrease weight
        evaluation = 0 # evaluation = 0 (bad) or 1 (good)
        self.update_weights(evaluation)
        pass


    def update_weights(self, evaluation):
        """ Update weights according to desired output """
        pass


    def make_decision(self, board, new_input):
        """ Use inputs and weights to make a play """
        lp = board.legal_places_for_roll_and_counter(roll, new_input['counters'])
        print lp
        return play

    def create_network(self, new_input_group, weight_group):
        """ Handle neural network """
        # TODO: Edit to include matching input, weight
	for i in new_input_group:
            self.create_neurons(i, weight_group)


    def create_neurons(self, new_input, weights):
        """ Create a neuron to accept input and come up with an output """
        # Do some calculation on input 
        # Assume # inputs == # weights
        # Use weights
        if len(weights) != len(new_inputs):
            print "Warning: length of inputs != length outputs"
        decision = []
        for i in new_input:
            for w in weights:
                decision.append(i*w)
        dec = sum(decision)/len(new_inputs)
        # Return output


if __name__ == '__main__':
    """ Use the neural network to play the Finito game here """
    sp = sorto.SortoPlayer(name='NeuralNet')
    #board = sorto.SortoBoard()
    board = sp._board
    neural_net = NeuralNetwork(board, all_counters)
    neural_net.initialize_weights()
    # for a number of games...
    for i in range(0, 10):
        sp.new_game(i)
        print "Table: ",  sp.examing_table()
        while not win:
            board = sp.examine_table()
            dice_roll = sp.play_roll()
            new_input = {'board':board, 
                         'counters':counters, 
                         'roll':dice_roll}
            decision = make_decision(sp, new_input)
        number_plays = find_number_plays()
        neural_net.game_history.append(number_plays)
        if i != 1: # Update after first game is over
            neural_net.evaluate_output(pattern)

         
        



    




